<script lang='ts' setup>
import { computed, PropType, reactive } from 'vue'
import { V2rayInboundVMess, V2rayVMessClient } from '@/apis/application/v2ray/structs.ts'
import { toCanvas } from 'qrcode'

declare type ShareLink = { add: string, port: string, aid: string, host: string, id: string, net: string, path: string, ps: string, scy: string, sni: string, tls: string, type: string, v: string }

const emits = defineEmits(['update:show'])
const props = defineProps({
  show: { required: true, type: Boolean },
  protocol: { required: true, type: Object as PropType<V2rayInboundVMess> }
})

const options = computed(() => {
  const options: {label: string, value: string}[] = []
  props.protocol!.clients.forEach((client: V2rayVMessClient) => {
    options.push({ label: client.id, value: client.id })
  })

  return options
})

const state = reactive<{ share_link: string, host: string, port: '' }>({ share_link: '', host: '', port: '' })

async function close(): Promise<void> {
  emits('update:show', false)
  state.share_link = state.host = state.port = ''
}

async function show_qrcode(value: string): Promise<void> {
  const link: ShareLink = { add: props.protocol!.inbound_listen, aid: '0', host: '', id: value, net: '', path: '', port: props.protocol!.inbound_port.toString(), ps: '', scy: 'auto', sni: '', tls: '', type: '', v: '2' }
  link.add = '' !== state.host ? state.host : link.add
  link.port = '' !== state.port ? state.port : link.port
  link.ps = `${link.add}:${link.port}`

  if (props.protocol!.stream_settings.enable) {
    link.tls = 'tls' === props.protocol!.stream_settings.tls_settings.security ? 'tls' : ''
    link.sni = props.protocol!.stream_settings.tls_settings.server_name

    switch (props.protocol!.stream_settings.network) {
      case 'tcp':
        link.net = 'tcp'
        link.type = props.protocol!.stream_settings.tcp_settings.header.type
        break
      case 'ws':
        link.net = 'ws'
        link.path = props.protocol!.stream_settings.websocket_settings.path
        break
      case 'kcp':
        link.net = 'kcp'
        link.type = props.protocol!.stream_settings.kcp_settings.header.type
        break
      case 'http':
        link.net = 'http'
        link.host = props.protocol!.stream_settings.http2_settings.host.join(',')
        link.path = props.protocol!.stream_settings.http2_settings.path
        break
      case 'quic':
        link.net = 'quic'
        link.type = props.protocol!.stream_settings.quic_settings.header.type
        link.host = props.protocol!.stream_settings.quic_settings.security
        link.path = props.protocol!.stream_settings.quic_settings.key
    }
  }

  const content = btoa(JSON.stringify(link))
  state.share_link = content
  await toCanvas(document.getElementById('qr-code'), `vmess://${content}`, { errorCorrectionLevel: 'H', width: 500 })
}
</script>

<template>
  <n-modal :show='props.show' class='v2ray-qrcode-modal' transform-origin='center' @update:show='close'>
    <n-card>
      <n-space vertical>
        <div>
          <n-space :wrap-item='false' align='center'>
            <div class='width-05'>
              <n-input-group>
                <n-input-group-label size='small'>服务器域名</n-input-group-label>
                <n-input v-model:value='state.host' placeholder='可以为空，为空时使用协议的监听地址' size='small' />
              </n-input-group>
            </div>
            <div class='flex-max'>
              <n-input-group>
                <n-input-group-label size='small'>端口</n-input-group-label>
                <n-input v-model:value='state.port' placeholder='可以为空，为空时使用协议的监听端口' size='small' />
              </n-input-group>
            </div>
          </n-space>
        </div>
        <div>
          <n-space :wrap-item='false' align='center'>
            <div class='flex-max'>
              <n-select :options='options' placeholder='选择客户端显示二维码' @update:value='show_qrcode' />
            </div>
          </n-space>
        </div>
        <div>
          <n-space align='center' justify='center'>
            <div>
              <canvas id='qr-code' />
            </div>
          </n-space>
        </div>
        <div>{{ state.share_link ? `vmess://${state.share_link}` : '' }}</div>
      </n-space>
    </n-card>
  </n-modal>
</template>

<style scoped>
.v2ray-qrcode-modal {
  width: 800px;
  height: 750px;
}
</style>
